Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve reliability of VT responses #17786

Merged
merged 2 commits into from
Aug 23, 2024

Conversation

lhecker
Copy link
Member

@lhecker lhecker commented Aug 23, 2024

  • Repurposes _sendInputToConnection to send output to the connection
    no matter whether the terminal is read-only or not.
    Now SendInput is the function responsible for the UI handling.
  • Buffers responses in a VT string into a single string
    before sending it as a response all at once.

This reduces the chances for the UI thread to insert cursor positions
and similar into the input pipe, because we're not constantly unlocking
the terminal lock anymore for every response. The only way now that
unrelated inputs are inserted into the input pipe is because the VT
requests (e.g. DA1, DSR, etc.) are broken up across >1 reads.

This also fixes VT responses in read-only panes.

Closes #17775

Validation Steps Performed

  • Repeatedly run echo ^[[c in cmd.
    DA1 responses don't stack & always stay the same ✅
  • Run nvim in WSL. Doesn't deadlock when pasting 1MB. ✅
  • Run the repro from Low reliability of VT replies #17775, which requests a ton of OSC 4
    (color palette) responses. Jiggle the cursor on top of the window.
    Responses never get split up. ✅

@microsoft-github-policy-service microsoft-github-policy-service bot added Issue-Bug It either shouldn't be doing this or needs an investigation. Area-Input Related to input processing (key presses, mouse, etc.) Priority-1 A description (P1) Product-Conpty For console issues specifically related to conpty labels Aug 23, 2024
Comment on lines -448 to -451
void ControlCore::SendInput(const std::wstring_view wstr)
{
_sendInputToConnection(wstr);
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SendInput now does what _sendInputToConnection previously did.
_sendInputToConnection is now a write-directly-to-connection function.

Comment on lines +2170 to +2174
if (!_pendingResponses.empty())
{
_sendInputToConnection(_pendingResponses);
_pendingResponses.clear();
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes the bug. It also fixes 2nd bug: We'd previously use the old _sendInputToConnection for responses but this would check whether we're read-only. We shouldn't do that for VT responses.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh this is clever. it replies with it immediately after the write that caused a reply?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah exactly. This is much better than before, because it's now processing an entire VT string atomically without unlocking in between. Not sure why I haven't done this from the get-go.

Copy link
Member

@carlos-zamora carlos-zamora left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work!

@carlos-zamora carlos-zamora merged commit b07589e into main Aug 23, 2024
20 checks passed
@carlos-zamora carlos-zamora deleted the dev/lhecker/17775-response-locking branch August 23, 2024 17:54
DHowett pushed a commit that referenced this pull request Aug 23, 2024
* Repurposes `_sendInputToConnection` to send output to the connection
  no matter whether the terminal is read-only or not.
  Now `SendInput` is the function responsible for the UI handling.
* Buffers responses in a VT string into a single string
  before sending it as a response all at once.

This reduces the chances for the UI thread to insert cursor positions
and similar into the input pipe, because we're not constantly unlocking
the terminal lock anymore for every response. The only way now that
unrelated inputs are inserted into the input pipe is because the VT
requests (e.g. DA1, DSR, etc.) are broken up across >1 reads.

This also fixes VT responses in read-only panes.

Closes #17775

* Repeatedly run `echo ^[[c` in cmd.
  DA1 responses don't stack & always stay the same ✅
* Run nvim in WSL. Doesn't deadlock when pasting 1MB. ✅
* Run the repro from #17775, which requests a ton of OSC 4
  (color palette) responses. Jiggle the cursor on top of the window.
  Responses never get split up. ✅

(cherry picked from commit b07589e)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmszgSK_Dw
Service-Version: 1.21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Input Related to input processing (key presses, mouse, etc.) Issue-Bug It either shouldn't be doing this or needs an investigation. Priority-1 A description (P1) Product-Conpty For console issues specifically related to conpty
Projects
Development

Successfully merging this pull request may close these issues.

Low reliability of VT replies
3 participants